package com.example.lib5.linkedList;


import java.util.Stack;

public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        //进行测试
        //先创建节点
        HeroNode2 heroNode = new HeroNode2(1, "唐三", "昊天宗");
        HeroNode2 heroNode1 = new HeroNode2(2, "小舞", "十万年魂兽");
        HeroNode2 heroNode2 = new HeroNode2(3, "宁荣荣", "七宝琉璃宗");
        HeroNode2 heroNode3 = new HeroNode2(4, "千仞雪", "武魂殿");
        //创建链表，并加入节点
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add(heroNode);
        myLinkedList.add(heroNode3);
        myLinkedList.add(heroNode1);
        myLinkedList.add(heroNode2);
        myLinkedList.list();
        HeroNode2 heroNodeNew = new HeroNode2(3, "海女斗罗", "海神岛");
        myLinkedList.update(heroNodeNew);
        myLinkedList.list();
        //对链表进行删除
        myLinkedList.delete(3);
        myLinkedList.list();


        
        

    }


    private static class HeroNode2 {
        private int no;
        private String name;
        private String background;
        private HeroNode2 next;
        private HeroNode2 pre;
        //背景
        public HeroNode2(int no, String name, String background) {
            this.no=no;
            this.name=name;
            this.background =background;
        }

        @Override
        public String toString() {
            return "HeroNode{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    ", background='" + background + '\'' +
                    '}';
        }
    }

    private static class MyLinkedList {
        //默认设置有一个头节点
        private HeroNode2 head=new HeroNode2(0,"","");

        public HeroNode2 getHead() {
            return head;
        }

        public void add(HeroNode2 heroNode) {
            HeroNode2 temp=head;
            //遍历出最后一个节点
            while (true) {
                if (temp.next==null) {
                    break;
                }
                //后移
                temp=temp.next;
            }
            //对最后一个节点进行赋值
            temp.next=heroNode;
            heroNode.pre=temp;
        }

        public void list() {
            //判断链表是否为空，如果是空的话，就没有必要遍历
            if (head.next==null) {
                System.out.println("链表为空");
                return;
            }
            System.out.println("链表结果打印如下：");
            //因为头节点不能动，所以我们需要一个辅助遍历来遍历
            HeroNode2 temp = head.next;
            while (true) {
                //判断是否为最后一个节点
                if (temp==null) {
                    break;
                }
                //输出节点的信息
                System.out.println(temp);
                //将temp后移，一定要小心
                temp=temp.next;
            }
        }

        /**
         * 下面的方法耦合性比较大，就是有什么就做什么。而addByOrder2里面的方法则是，分成两部分：获取状态，根据状态来进行逻辑处理，这样比较解耦，高内聚（统一处理）
         * @param heroNode
         */
        public void addByOrder(HeroNode2 heroNode) {
            //判断链表是否为空链表，如果是空链表的话，就直接加入
            HeroNode2 temp =head;

            //链表不为空的情况
            //遍历获取链表比heroNode.no大的值的前一个
            while (true) {
                //如果链表存在了，就不添加进去
                if (temp.next==null) {
                    temp.next=heroNode;
                    break;
                }else
                if (temp.next.no==heroNode.no) {
                    System.out.println("链表已经存在了，无法在添加进去");
                    break;
                }else
                //下面是获取比heroNode.no大的值，然后temp就是前一个
                if (temp.next.no>heroNode.no) {
                    //先让heroNode的next指向比它大值得那个
                    heroNode.next=temp.next;
                    //再让上一个指向添加的值
                    temp.next=heroNode;
                    break;
                }else if (temp.next==null){
                    temp.next=heroNode;
                    break;
                }
                //如果不是的话，就后移，便于继续遍历
                temp=temp.next;
            }
        }

        /**
         * ，分成两部分：获取状态，根据状态来进行逻辑处理，这样比较解耦，高内聚（统一处理）
         * @param heroNode
         */
        public void addByOrder2(HeroNode2 heroNode){
            //因为头节点不能动，因此我们仍然通过一个辅助指针来帮助找到添加的位置
            //要找到单链表的前一个，如果找到的是这个，那么久只能为这个赋值，
            HeroNode2 temp = this.head;
            boolean flag=false;
            while (true) {
                if (temp.next==null) {//说明是链表的最后一个了，直接添加即可
                    break;
                }
                if (temp.next.no>heroNode.no) {
                    break;
                }else if (temp.next.no==heroNode.no){//这个编号已经添加过了
                    flag=true;
                    break;
                }
                temp=temp.next;
            }
            //判断flag的值
            if (flag) {
                System.out.printf("准备插入的英雄编号 %d 已经存在了，不能加入\n",heroNode.no);
            }else {
                //插入得到链表中，temp的后面
                heroNode.next=temp.next;
                temp.next=heroNode;
            }
        }

        public void update(HeroNode2 heroNodeNew) {
            //判断链表是否为空
            if (head.next==null) {
                System.out.println("链表为空，无法进行修改，可以先添加");
                return;
            }
            //设置一个标记，true表示存在这个编号，false表示不存在这个编号
            boolean flag=false;
            HeroNode2 temp = head.next;
            while (true) {
                if (temp==null) {
                    //表示链表为空
                    System.out.println("链表已经遍历完了");
                    flag=false;
                    break;
                }
                //根据编号来确定是否有得修改
                if (temp.no==heroNodeNew.no) {
                    flag=true;
                    break;
                }
                    //后移
                    temp=temp.next;

            }
            if (flag==true) {
                //如果是存在就进行修改
                temp.name=heroNodeNew.name;
                temp.background=heroNodeNew.background;
            }else {
                System.out.println("不存在此编号，所以无法修改");
            }

        }

        public void delete(int no) {
            //判断链表是否为空
            if (head.next==null) {
                System.out.println("链表为空，无法删除");
                return;
            }
            HeroNode2 temp = head.next;
            boolean flag=false;//用于标记是否有得删除，有true，没有false

            //链表不为空的话进行遍历，然后找到要删除的前一个节点
            while (true) {
                //判断链表是否为最后一个了，如果是的话，就break
                if (temp==null) {
                    System.out.println("链表已经遍历完了，找不到，所以无法删除");
                    flag=false;
                    break;
                }
                if (temp.no==no) {
                    //表示找到了，直接标记为找到
                    flag=true;
                    break;
                }
                //没有找到，就后移
                temp=temp.next;
            }
            if (flag==true) {
                temp.pre.next=temp.next;
                if (temp.next!=null) {
                    temp.next.pre=temp.pre;
                }

            }else {
                System.out.println("不存在要删除的链表节点");
            }
        }



    }
}

